package com.uxwine.alarm;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Parcel;

import com.uxwine.alarm.alert.AlarmNotify2;

public class AlertMgr
{	

	Context mCtx;
	Snooze mSnooze;
	
	static AlertMgr mInstance;
	public static synchronized AlertMgr getInstance(Context ctx)
	{
		if(null == mInstance)
			mInstance = new AlertMgr(ctx.getApplicationContext());
		return mInstance;
	}
	
	private AlertMgr(Context ctx)
	{
		mCtx = ctx;
		mSnooze = Snooze.getInstance(mCtx);
	}	
	
	/**
     * Disables alert in AlarmManger and StatusBar.
     *
     * @param id Alarm ID.
     */
    public void disable() 
    {
        AlarmManager am = (AlarmManager)mCtx.getSystemService(Context.ALARM_SERVICE);
        PendingIntent sender = PendingIntent.getBroadcast(
                mCtx, 0, new Intent(Cmd.ACTION_ALARM_ALERT),
                PendingIntent.FLAG_CANCEL_CURRENT);
        am.cancel(sender);
        
        AlarmNotify2.cancelAlarm(mCtx);
    }
	
	/**
     * Sets alert in AlarmManger and StatusBar.  This is what will
     * actually launch the alert when the alarm triggers.
     *
     * @param alarm Alarm.
     * @param atTimeInMillis milliseconds since epoch
     */
    public void enable(final Alarm alarm, final long atTimeInMillis) 
    {
        AlarmManager am = (AlarmManager)mCtx.getSystemService(Context.ALARM_SERVICE);

        Intent intent = new Intent(Cmd.ACTION_ALARM_ALERT);
        intent.putExtra(Cmd.Alert.EXTRA_RAW, toBytes(alarm));

        PendingIntent sender = PendingIntent.getBroadcast(
                mCtx, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        am.set(AlarmManager.RTC_WAKEUP, atTimeInMillis, sender);
        
        //在状态栏中显示闹钟提醒
        AlarmNotify2.notifyAlarm(mCtx, alarm);
    }   
    
    
    public void snooze(Alarm alarm)
    {
    	Cmd cmd = new Cmd(Cmd.ACTION_ALARM_SNOOZE);
    	cmd.put(Cmd.Alert.EXTRA_ALARM, alarm);
    	cmd.broadcast(mCtx);
    	AlarmNotify2.notifySnoozed(mCtx, alarm);
    }
    
    public void showTimeout(Alarm alarm)
    {
    	Cmd cmd = new Cmd(Cmd.ACTION_ALARM_TIMEOUT);
    	cmd.put(Cmd.Alert.EXTRA_ALARM, alarm);
    	cmd.broadcast(mCtx);
    	AlarmNotify2.notifyTimeout(mCtx, alarm, 0);
    }
    
    public void cancel(int id)
    {
    	AlarmNotify2.cancel(mCtx, id);
    	//XXX need cancel the current alert, such as ring and ui.
    	//we can send broadcast to do it.
    	Cmd cmd = new Cmd(Cmd.ACTION_ALARM_KILLED);
    	cmd.put(Cmd.Alert.EXTRA_ALARM_ID, id);
    	cmd.broadcast(mCtx);
    }
    
    
    private byte[] toBytes(Alarm alarm)
    {
    	// XXX: This is a slight hack to avoid an exception in the remote
        // AlarmManagerService process. The AlarmManager adds extra data to
        // this Intent which causes it to inflate. Since the remote process
        // does not know about the Alarm class, it throws a
        // ClassNotFoundException.
        //
        // To avoid this, we marshall the data ourselves and then parcel a plain
        // byte[] array. The AlarmReceiver class knows to build the Alarm
        // object from the byte[] array.
        Parcel out = Parcel.obtain();
        alarm.writeToParcel(out, 0);
        out.setDataPosition(0);
        return out.marshall();
    }
}
